/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import dao.exception.DAOConnectionException;
import dao.exception.DAOCoursException;
import dao.interfaces.DAOCours;
import dao.interfaces.DAOExamen;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import model.Cour;
import model.Enseignant;
import model.Examen;
import model.Note;

/**
 *
 * @author Paul
 */
public class DAOCoursImpl implements DAOCours {

    private DAOInit daoConnection;

    public DAOCoursImpl(DAOInit daoConnection) {
        this.daoConnection = daoConnection;
    }

    public ArrayList<Enseignant> rechercheProf(int id_cour) throws DAOCoursException {
        ArrayList<Enseignant> array = new ArrayList<Enseignant>();
        PreparedStatement st = null;
        Enseignant p = null;
        try {
            Connection conn = daoConnection.getConnection();
            String query = "SELECT DISTINCT p.login, p.password, p.nom, p.prenom, e.id_enseignant, e.id_personne, p.typeUtilisateur FROM personne p, enseignant e, enseig_cour_asso eca, cour c WHERE p.id_personne = e.id_personne AND eca.id_enseignant = e.id_enseignant AND eca.id_cour =" + id_cour + ";";
            st = conn.prepareStatement(query);
            ResultSet res = st.executeQuery(query);
            while (res.next()) {
                String log = res.getString("login");
                String password = res.getString("password");
                String nom = res.getString("nom");
                String prenom = res.getString("prenom");
                int idp = res.getInt("id_personne");
                int ide = res.getInt("id_enseignant");
                String type = res.getString("typeUtilisateur");
                java.sql.Date d = null;
                array.add(new Enseignant(ide, idp, nom, prenom, d, type, log, password));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return array;
    }

    public int create(String nomCour, float coeff) throws DAOCoursException {
        boolean create = false;
        boolean recherche = false;
        int idCours = 0;
        String query = "INSERT INTO `cour`( `nom`, `coefficient`) VALUES (?,?)";//preparation de la requete
        recherche = findCreateCour(nomCour);
        if (recherche == true) {
            throw new DAOCoursException("Le cours existe déjà.");
        }
        /**
         * initialisation des variables *
         */
        int nb = 0;
        int autoIncKeyFromApi = -1;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setString(1, nomCour);
            ps.setFloat(2, coeff);
            nb = ps.executeUpdate();//lancement de la requête
            ResultSet rs = ps.getGeneratedKeys();//recupération du résultat
            if (rs.next()) {//récuperation de l'id 
                autoIncKeyFromApi = rs.getInt(1);
                System.out.println(autoIncKeyFromApi);
                if (nb >= 1) {
                    idCours = autoIncKeyFromApi;
                }
            }
            else {
                throw new DAOCoursException("Problème d'insertion du cours : voir l'administrateur");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return idCours;
    }

    public HashMap<String, Float> getAllNoteExamFromCour(int id_etudiant, int id_cour, ArrayList<Examen> exams, Note n) throws DAOCoursException {
        HashMap<String, Float> map = new HashMap<String, Float>();
        for (Examen exam : exams) {
            map.put(exam.getNomExamen(), n.getNote());
        }
        for (Map.Entry<String, Float> entry : map.entrySet()) {
            System.out.println(entry.getKey().toString() + " " + entry.getValue().toString());
        }
        return map;
    }

    public boolean findCreateCour(String nomCour) {
        String query = "SELECT c.nom FROM cour c WHERE c.nom = '" + nomCour + "'";
        int nb = 0;
        Statement ps = null;
        boolean del = false;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();
            ps = conn.createStatement();
            ResultSet res = ps.executeQuery(query);
            while (res.next()) {
                String nom = res.getString("nom");
                if (res.first()) {
                    nb = nb + 1;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        if (nb >= 1) {

            del = true;
        }
        return del;
    }

    public boolean deleteAttributeEudiant(int id_Etudiant, int id_Cour) {
        String query = "DELETE FROM etu_cour_asso WHERE id_eleve = ? AND id_cour = ?";//preparation de la requete
        /**
         * initialisation des variables *
         */
        int nb = 0;
        boolean del = false;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, id_Etudiant);
            ps.setInt(2, id_Cour);
            nb = ps.executeUpdate();//lancement de la requête
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (nb >= 1) {
            del = true;
        }
        return del;

    }

    public void attributeEudiant(int id_Etudiant, int id_Cour) throws DAOCoursException {
        String query = "insert into etu_cour_asso (id_eleve,id_cour) values (?,?)";//preparation de la requete
        /**
         * initialisation des variables *
         */
        int nb = 0;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, id_Etudiant);
            ps.setInt(2, id_Cour);
            nb = ps.executeUpdate();//lancement de la requête
        } catch (SQLException e) {
            throw new DAOCoursException("L'étudiant(e) sélectionné(e) est déjà associé(e) à un cours");
        }

    }

    public boolean createCourExam(int idCour, int idExamen) throws DAOCoursException {
        boolean del = false;
        String query = "INSERT INTO `cour_exam_asso`(`id_cour`, `id_examen`) VALUES (?,?)";//preparation de la requete
        /**
         * initialisation des variables *
         */
        int nb = 0;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, idCour);
            ps.setInt(2, idExamen);
            nb = ps.executeUpdate();//lancement de la requête
            if (nb >= 1) {
                del = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return del;
    }

    public boolean attributeProfesseur(int id_prof, int id_Cour) throws DAOCoursException {
        String query = "insert into enseig_cour_asso (id_enseignant,id_cour) values (?,?)";//preparation de la requete
        boolean del = false;
        /**
         * initialisation des variables *
         */
        int nb = 0;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, id_prof);
            ps.setInt(2, id_Cour);
            nb = ps.executeUpdate();//lancement de la requête
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return del;

    }

    public boolean deleteAttributeProfesseur(int id_prof, int id_Cour) {
        String query = "DELETE FROM enseig_cour_asso WHERE id_enseignant=? AND id_cour=?";//preparation de la requete
        boolean del = false;
        /**
         * initialisation des variables *
         */
        int nb = 0;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, id_prof);
            ps.setInt(2, id_Cour);
            nb = ps.executeUpdate();//lancement de la requête
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return del;

    }

//Trouver les cour associé a un etudiant
    public ArrayList<Cour> findCoursEtudiant(int id_etudiant) throws DAOCoursException {
        String query = "SELECT c.id_cour, c.nom,c.coefficient FROM cour c, etu_cour_asso e WHERE e.id_cour = c.id_cour AND e.id_eleve =" + id_etudiant + ";";
        ArrayList<Cour> cours = new ArrayList<Cour>();
        Cour cour = null;
        Statement ps = null;
        try {
            Connection conn = daoConnection.getConnection();
            ps = conn.createStatement();
            ResultSet res = ps.executeQuery(query);
            while (res.next()) {
                int id = res.getInt("id_cour");
                String nom = res.getString("nom");
                float coef = res.getFloat("coefficient");
                cour = new Cour(id, nom, coef);
                cours.add(cour);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return cours;
    }

    public ArrayList<Cour> findCoursProf(int id_prof) throws DAOCoursException {
        String query = "SELECT c.id_cour, c.nom,c.coefficient FROM cour c, enseig_cour_asso e WHERE e.id_cour = c.id_cour AND e.id_enseignant =" + id_prof + ";";
        ArrayList<Cour> cours = new ArrayList<Cour>();
        Cour cour = null;
        Statement ps = null;
        try {
            Connection conn = daoConnection.getConnection();
            ps = conn.createStatement();
            ResultSet res = ps.executeQuery(query);
            while (res.next()) {
                int id = res.getInt("id_cour");
                String nom = res.getString("nom");
                float coef = res.getFloat("coefficient");
                cour = new Cour(id, nom, coef);
                cours.add(cour);
            }
            if (cours.isEmpty()) {
                throw new DAOCoursException("Erreur de récupération des cours : veuillez contacter l'administrateur du site.");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return cours;
    }

    public boolean update(Cour obj) {
        String query = "UPDATE `cour` SET `id_cour`= ?,`nom`= ?,`coefficient`= ? WHERE `id_cour` = ?";
        int nb = 0;
        boolean del = false;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete

            /**
             * remplacement des points d'interogation dans la query par les
             * variables*
             */
            ps.setInt(1, obj.getIdCour());
            ps.setString(2, obj.getNomCour());
            ps.setFloat(3, obj.getCoefCour());
            ps.setInt(4, obj.getIdCour());
            nb = ps.executeUpdate();//lancement de la requête
            if (nb >= 1) {
                del = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return del;
    }

    public boolean delete(int idCour) {
        String query = "DELETE FROM `cour` WHERE `id_cour` = " + idCour + " ?";
        int nb = 0;
        boolean del = false;
        PreparedStatement ps = null;

        /**
         * lancement de la connexion à la bd et de la requete *
         */
        try {
            Connection conn = daoConnection.getConnection();//Creation de la connexion
            ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);//preparation de la requete
            nb = ps.executeUpdate();//lancement de la requête
            if (nb >= 1) {
                del = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return del;
    }

    public ArrayList<Cour> getAll() {
        String query = "";
        return findGeneral(query);
    }

    public Cour find(int id) {
        String query = "select * from cour where id_cour=" + id + ";";
        Cour cour = null;
        if (findGeneral(query).size() != 0) {
            cour = findGeneral(query).get(0);
        }
        return cour;
    }

    public ArrayList<Cour> findCoursCoeff(int idEleve) {
        ArrayList<Cour> cours = new ArrayList<Cour>();
        Cour cour = null;
        Statement ps = null;
        try {
            Connection conn = daoConnection.getConnection();
            String query = "SELECT c.id_cour, c.nom, c.coefficient FROM etu_cour_asso cea, cour c WHERE c.id_cour = cea.id_cour AND cea.id_eleve = " + idEleve + ";";
            ps = conn.createStatement();
            ResultSet res2 = ps.executeQuery(query);
            while (res2.next()) {
                int id = res2.getInt("id_cour");
                String nom = res2.getString("nom");
                float coeff = res2.getFloat("coefficient");
                cour = new Cour(id, nom, coeff);
                cours.add(cour);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return cours;
    }

//---------------------------------------------------------private method--------------------------------------------------------------------//
    private ArrayList<Cour> findGeneral(String requete) {
        ArrayList<Cour> cours = new ArrayList<Cour>();
        Statement st = null;
        Cour cour = null;
        try {
            Connection conn = daoConnection.getConnection();
            st = conn.createStatement();
            ResultSet res = st.executeQuery(requete);
            while (res.next()) {
                cour = createObject(res);
                cours.add(cour);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return cours;
    }

    private Cour createObject(ResultSet res) {
        Cour cour = null;
        try {
            int id = res.getInt("id_cour");
            String nom = res.getString("nom");
            cour = new Cour(id, nom);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return cour;
    }
}
